package org.lhl.readruler.manager

import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.os.Handler
import android.os.Looper
import com.blankj.utilcode.util.ActivityUtils
import io.reactivex.Flowable
import io.reactivex.Observable
import io.reactivex.disposables.Disposable
import io.reactivex.processors.PublishProcessor
import lhl.kotlinextends.*
import org.lhl.readruler.DeviceActivity
import org.lhl.readruler.connection.*
import org.lhl.readruler.utils.DataTool
import java.util.concurrent.TimeUnit

/**
 * Author:  LuoHaoLun
 * Email :  506503279@qq.com
 * Date  :  2019/8/7
 */
object DeviceManager {

    private val mBluetoothAdapter by lazy { BluetoothAdapter.getDefaultAdapter() }
    fun isOpenBluetooth() = mBluetoothAdapter.isEnabled
    private val bleCallBack by lazy {
        BluetoothAdapter.LeScanCallback { device, rssi, scanRecord ->
            processor.onNext(device)
        }
    }

    fun openBluetooth(): Observable<*> {
        mBluetoothAdapter.enable()
        return Observable.timer(100, TimeUnit.MILLISECONDS).repeatUntil { mBluetoothAdapter.isEnabled }
    }

    fun closeBluetooth(): Observable<*> {
        stopDiscover()
        mBluetoothAdapter.disable()
        return Observable.timer(100, TimeUnit.MILLISECONDS).repeatUntil { !mBluetoothAdapter.isEnabled }
    }

    fun startDiscover() {
        mBluetoothAdapter.startLeScan(bleCallBack)
    }

    fun stopDiscover() {
        if (mBluetoothAdapter.isEnabled)
            mBluetoothAdapter.stopLeScan(bleCallBack)
    }


    private val processor = PublishProcessor.create<Any>().toSerialized()
    private val bleConnection by lazy { BleBluetoothConnection(processor, RulerParser()) }
    private var dispose: Disposable? = null
    fun connectState() = bleConnection.connectState
    fun isConnected() = bleConnection.connectState == ConnectState.CONNECTED
    fun isConnecting() = bleConnection.connectState == ConnectState.CONNECTING
    fun isDisConnect() = bleConnection.connectState == ConnectState.DISCONNECTED
    var isMeasuring = false //是否在测量中
    var device: BluetoothDevice? = null
    var deviceId: String? = null
    var deviceState = ""
    var isInvalidDevice = true
    private var mainHandler = Handler(Looper.getMainLooper())
    private var breakDialog: TDialog? = null
    private var watchDog: Disposable? = null
    private val RESPONSE_NOT_BEGIN = "0a0b1e10070000e7e8"            //未开始作业
    private val COMMAND_GET_DEVICE_ID = "0a0b1600000000e7e8"            //获取设备ID
    private val COMMAND_GET_DEVICE_STORAGE = "0a0b2300000000e7e8"       //获取设备存储数据

    fun getDeviceStorage() {
        val bytes = DataTool.hexStringToBytes(COMMAND_GET_DEVICE_STORAGE)
        send(bytes)
    }

    fun send(bytes: ByteArray) {
        bleConnection.send(bytes)
    }

    fun connect(device: BluetoothDevice) {
        this.device = device
        bleConnection.connectDevice(device)
        dispose?.dispose()
        dispose = registerChangeListener().subscribe({
            when (it.attribute) {
                Event.DISCONNECTED -> {
//                    if (deviceId != null)
//                        SpeechManager.play(R.raw.bluetooth_break)
                    deviceId = null
                    deviceState = ""
                    if (ActivityUtils.getTopActivity() !is DeviceActivity) {
                        breakDialog?.dismiss()
                        mainHandler.post { breakDialog = TDialog("设备连接已断开", CANCEL_BACK).show() }
                    }
                }
                Event.CONNECTED -> {
                    deviceId = null
                    deviceState = ""
                    val bytes = DataTool.hexStringToBytes(COMMAND_GET_DEVICE_ID)
                    send(bytes)
                    Observable.timer(2000, TimeUnit.MILLISECONDS).repeatUntil { deviceId != null }.subscribe {
                        "发送获取设备ID".e()
                        send(bytes)
                    }

                    watchDog?.dispose()
                    watchDog = Observable.timer(4, TimeUnit.MINUTES).repeatUntil { isDisConnect() }.subscribe {
                        "发送心跳3333".e()
                        send(byteArrayOf(0x01, 0x01, 0x01))
                    }
                }
                Event.DEVICE_ID -> {
                    deviceId = it.value as String
                }
            }
        }) {
            "蓝牙监听出错".toastLong()
            it.e()
        }
    }

    fun disConnect() {
        bleConnection.disConnect()
        dispose?.dispose()
    }

    fun registerChangeListener(): Flowable<AttEvent> {
        return processor.ofType(AttEvent::class.java)
    }

    fun registerBleDiscoverListener(): Flowable<BluetoothDevice> {
        return processor.ofType(BluetoothDevice::class.java)
    }


}